﻿using EnvDTE;
using SolidEdgeFramework;
using SolidEdgePart;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Metadata.W3cXsd2001;
using System.Text;
using System.Threading.Tasks;
using System.Web.UI.WebControls.WebParts;
using TGCommunity;

namespace TGComacAddin.command
{
    internal class TGGetFacePoint: SolidEdgeFramework.ISECommandEvents, SolidEdgeFramework.ISEMouseEvents, SolidEdgeFramework.ISELocateFilterEvents
    {
        private ConnectionPointController _connectController=null;
        private SolidEdgeFramework.Mouse _mouse = null;
        private PartDocument _partDoc = null;
        private UInt64 _destFaceId;
        private Int64 _destPointNum;
        private Int64 _curPointIdx = 0;
        private string _prompStr;
        private SelectStatus _status = SelectStatus.Running;
        private TGComacAddin.GetMousePointRes _res;

        public TGComacAddin.GetMousePointRes Result { 
            get=> _res;
            set => _res = value;
        } 
        public SelectStatus Status { get => _status; 
            set => _status = value;
        }

        public TGGetFacePoint(UInt64 destFaceId)
        {
            _destFaceId = destFaceId;
        }
        public TGGetFacePoint(SolidEdgeFramework.Mouse mouse, SolidEdgeFramework.Command cmd, PartDocument partDoc, 
            UInt64 destFaceId,Int64 pointNum)
        {
            _partDoc = partDoc;
            _connectController = new ConnectionPointController(this);
            _connectController.AdviseSink<SolidEdgeFramework.ISEMouseEvents>(mouse);
            _connectController.AdviseSink<SolidEdgeFramework.ISECommandEvents>(cmd);
            _connectController.AdviseSink<SolidEdgeFramework.ISELocateFilterEvents>(mouse);
            _mouse = mouse;

            _destFaceId = destFaceId;
            _destPointNum = pointNum;
            _prompStr = string.Format("请在指定面上一点单击/右键或ESC键取消");
        }

        void SolidEdgeFramework.ISECommandEvents.Activate()
        {

            _mouse.ScaleMode = 0;                // Design model coordinates.
            _mouse.WindowTypes = 1;              // Graphic window's only please.
            _mouse.EnabledDrag = true;
            _mouse.EnabledMove = true;   // Request move events.
            _mouse.LocateMode = (int)SolidEdgeConstants.seLocateModes.seLocateSimple;
            _mouse.ClearLocateFilter();
            _mouse.AddToLocateFilter((int)SolidEdgeConstants.seLocateFilterConstants.seLocateFace);
            
            _mouse.GroupLocateMode = 2;
            _status = SelectStatus.Running;
            _partDoc.Application.StatusBar = _prompStr;
        }

        public void Deactivate()
        {
            _status = SelectStatus.Cancel;
            return;
        }

        public void Terminate()
        {
            _connectController.UnadviseAllSinks();
            if (_status != SelectStatus.Success)
            {
                _status = SelectStatus.Failed;
                _res.ErrorCode= (UInt32)_status;
            }
            return;
        }

        public void Idle(int lCount, out bool pbMore)
        {
            pbMore = false;
        }

        public void KeyDown(ref short KeyCode, short Shift)
        {
            return;
        }

        public void KeyPress(ref short KeyAscii)
        {
            return;
        }

        public void KeyUp(ref short KeyCode, short Shift)
        {
            return;
        }

        void ISEMouseEvents.MouseDown(short sButton, short sShift, double dX, double dY, double dZ, object pWindowDispatch, int lKeyPointType, object pGraphicDispatch)
        {
            const short vbLeftButton = 1;
            const short vbRightButton = 2;
            if (sButton== vbRightButton)
            {
                _partDoc.Application.AbortCommand(true);
            }
            return;
        }

        void ISEMouseEvents.MouseUp(short sButton, short sShift, double dX, double dY, double dZ, object pWindowDispatch, int lKeyPointType, object pGraphicDispatch)
        {
            return;
        }

        void ISEMouseEvents.MouseMove(short sButton, short sShift, double dX, double dY, double dZ, object pWindowDispatch, int lKeyPointType, object pGraphicDispatch)
        {
            _partDoc.Application.StatusBar= _prompStr;
            return;
        }

        private List<double> _x = new List<double>();
        private List<double> _y = new List<double>();
        private List<double> _z = new List<double>();

        void ISEMouseEvents.MouseClick(short sButton, short sShift, double dX, double dY, double dZ, object pWindowDispatch, int lKeyPointType, object pGraphicDispatch)
        {
            if(null==pGraphicDispatch)
                return;
            try
            {
                //SolidEdgeGeometry.Face face = pGraphicDispatch as SolidEdgeGeometry.Face;
                //double[] ptSpace = new double[3] { dX, dY, dZ };
                //face.FindClosestPoint(ptSpace.ToArray(), out Array closestPt);
                //double[] ptClosest = closestPt.Cast<double>().ToArray();
                SolidEdgeFramework.Window window =pWindowDispatch as SolidEdgeFramework.Window;
                window.View.Locate((int)dX, (int)dY, 0, out double ox, out double oy, out double oz);
                _x.Add(ox);
                _y.Add(oy);
                _z.Add(oz);
                _curPointIdx++;

                if(_destPointNum== _curPointIdx)
                {
                    _status = SelectStatus.Success;
                    _res = new TGComacAddin.GetMousePointRes { ErrorCode = (UInt32)_status,X=_x.ToArray(),Y=_y.ToArray(),Z=_z.ToArray() };
                    _partDoc.Application.AbortCommand(true);
                }
                else
                {
                    _prompStr = "请再选择一个点/右键或ESC键取消";
                    _partDoc.Application.StatusBar = _prompStr;
                }
            }
            catch (Exception e)
            {

            }

            return;
        }

        void ISEMouseEvents.MouseDblClick(short sButton, short sShift, double dX, double dY, double dZ, object pWindowDispatch, int lKeyPointType, object pGraphicDispatch)
        {
            return;
        }

        void ISEMouseEvents.MouseDrag(short sButton, short sShift, double dX, double dY, double dZ, object pWindowDispatch, short DragState, int lKeyPointType, object pGraphicDispatch)
        {
            return;
        }

        void ISELocateFilterEvents.Filter(object pGraphicDispatch, out bool vbValid)
        {
            vbValid = false;
            if (pGraphicDispatch == null)
            {
                return;
            }
            SolidEdgeGeometry.Face face = pGraphicDispatch as SolidEdgeGeometry.Face;
            UInt64 faceId= _partDoc.GetEntityID(face);
            if (faceId == _destFaceId)
            {
                vbValid = true;
            }

        }
    }
}
